/** @file               sw_thread.h
 *  @copyright          Copyright (C) 2006-2026 flyfish (tenggui_fu@126.com)
 *  @brief              This file is part of the swallow library
 *  @author             $Author: flyfish $
 *  @version            $Rev: 419 $
 *  @date               $Date: 2017-01-08 21:40:53 +0800 (周日, 08 1月 2017) $
 */
#ifndef __SW_THREAD_H__
#define __SW_THREAD_H__

#ifndef WIN32
#include <limits.h>
#include <pthread.h>
#endif

#ifdef __cplusplus
extern "C" {
#endif

#ifdef WIN32
typedef HANDLE SW_PROCESS;
typedef HANDLE SW_THREAD;
#define SW_INVALID_THREAD (SW_THREAD)NULL
#define SW_INVALID_PROCESS (SW_PROCESS)NULL
#else
typedef pid_t SW_PROCESS;
typedef pthread_t SW_THREAD;
#define SW_INVALID_THREAD (SW_THREAD)(-1)
#define SW_INVALID_PROCESS (SW_PROCESS)(-1)
#endif

typedef SW_VOID *SW_THREAD_ONCE;
#define SW_INVALID_THREAD_ONCE (SW_THREAD_ONCE)NULL

typedef SW_RET (*SW_THREAD_PROC)(SW_UINT32, ...);
typedef SW_RET (*SW_THREAD_ONCE_PROC)(SW_VOID);

typedef enum _SW_THREAD_DETACH_STATE
{
    SW_TDS_JOINABLE,
    SW_TDS_DETACHED,
    SW_TDS_INVALID = -1
}SW_THREAD_DETACH_STATE;

typedef enum _SW_THREAD_SCHED_POLICY
{
    SW_TSP_RR,
    SW_TSP_FIFO,
    SW_TSP_OTHER,
    SW_TSP_INVALID = -1
}SW_THREAD_SCHED_POLICY;

#define SW_THREAD_PRIO_MIN      0
#define SW_THREAD_PRIO_MAX      100
#define SW_THREAD_PRIO_LEVEL    (SW_THREAD_PRIO_MAX - SW_THREAD_PRIO_MIN) / 6
#define SW_THREAD_PRIO_LOWEST   SW_THREAD_PRIO_MIN
#define SW_THREAD_PRIO_LOWER    (SW_THREAD_PRIO_MIN + SW_THREAD_PRIO_LEVEL)
#define SW_THREAD_PRIO_LOW      (SW_THREAD_PRIO_MIN + SW_THREAD_PRIO_LEVEL * 2)
#define SW_THREAD_PRIO_MID      (SW_THREAD_PRIO_MIN + SW_THREAD_PRIO_LEVEL * 3)
#define SW_THREAD_PRIO_HIGH     (SW_THREAD_PRIO_MIN + SW_THREAD_PRIO_LEVEL * 4)
#define SW_THREAD_PRIO_HIGHER   (SW_THREAD_PRIO_MIN + SW_THREAD_PRIO_LEVEL * 5)
#define SW_THREAD_PRIO_HIGHEST  SW_THREAD_PRIO_MAX

#ifdef WIN32
#define SW_THREAD_STACK_MIN     (1 << 20)
#else
#define SW_THREAD_STACK_MIN     (32 << 10)
#endif

#define SW_THREAD_STACK_MAX     0

SW_API SW_RET SW_InitThreadAPI(SW_VOID);
SW_API SW_RET SW_RunThreadAPI(SW_VOID);
SW_API SW_RET SW_StopThreadAPI(SW_VOID);
SW_API SW_RET SW_ExitThreadAPI(SW_VOID);
SW_API SW_THREAD SW_CreateThread(const SW_CHAR *pName, SW_UINT32 prio, SW_UINT32 stackSize, SW_THREAD_PROC proc, SW_UINT32 argNum, ...);
SW_API SW_THREAD SW_CreateThreadEx(const SW_CHAR *pName, SW_UINT32 prio, SW_UINT32 stackSize, SW_THREAD_SCHED_POLICY policy, const SW_VOID *pData, SW_UINT32 dataLen, SW_THREAD_PROC proc, SW_UINT32 argNum, ...);
SW_API SW_RET SW_CancelThread(SW_THREAD thread);
SW_API SW_UINT32 SW_GetThreadCount(SW_VOID);
SW_API SW_BOOL SW_IsThreadEqual(SW_THREAD thread1, SW_THREAD thread2);
SW_API SW_RET SW_ThreadSleep(SW_UINT32 sec);
SW_API SW_RET SW_ThreadMSleep(SW_UINT32 msec);
SW_API SW_RET SW_ThreadUSleep(SW_UINT32 usec);
SW_API SW_BOOL SW_IsThreadAlive(SW_THREAD thread);
SW_API SW_THREAD SW_GetThreadSelf(SW_VOID);
SW_API SW_UINT32 SW_GetThreadIdSelf(SW_VOID);
SW_API SW_PROCESS SW_GetProcessSelf(SW_VOID);
SW_API SW_UINT32 SW_GetProcessIdSelf(SW_VOID);
SW_API const SW_CHAR *SW_GetThreadNameSelf(SW_VOID);
SW_API SW_RET SW_GetThreadName(SW_THREAD thread, SW_CHAR *pName, SW_UINT32 nameLen);
SW_API SW_VOID *SW_GetThreadDataSelf(SW_VOID);
SW_API SW_RET SW_GetThreadData(SW_THREAD thread, SW_VOID *pData, SW_UINT32 dataLen);
SW_API SW_THREAD_DETACH_STATE SW_GetThreadDetachState(SW_THREAD thread); 
SW_API SW_VOID *SW_GetThreadStackAddr(SW_THREAD thread);
SW_API SW_UINT32 SW_GetThreadStackSize(SW_THREAD thread);
SW_API SW_UINT32 SW_GetThreadGuardSize(SW_THREAD thread);
SW_API SW_UINT32 SW_GetThreadPrio(SW_THREAD thread);
SW_API SW_THREAD_SCHED_POLICY SW_GetThreadSchedPolicy(SW_THREAD thread);
SW_API SW_UINT32 SW_GetThreadTid(SW_THREAD thread);
SW_API SW_UINT32 SW_GetThreadPid(SW_THREAD thread);
SW_API SW_UINT32 SW_GetThreadPpid(SW_THREAD thread);
SW_API SW_UINT32 SW_GetThreadTidSelf(SW_VOID);
SW_API SW_UINT32 SW_GetThreadPidSelf(SW_VOID);
SW_API SW_UINT32 SW_GetThreadPpidSelf(SW_VOID);
SW_API SW_UINT32 SW_GetProcessPcpu(SW_UINT32 pid);
SW_API SW_UINT32 SW_GetThreadPcpu(SW_UINT32 pid, SW_UINT32 tid);
SW_API SW_UINT32 SW_GetProcessPmem(SW_UINT32 pid);
SW_API SW_UINT32 SW_GetThreadPmem(SW_UINT32 pid, SW_UINT32 tid);
SW_API SW_UINT32 SW_GetProcessMem(SW_UINT32 pid);
SW_API SW_UINT32 SW_GetThreadMem(SW_UINT32 pid, SW_UINT32 tid);
SW_API SW_RET SW_SetThreadExitFlag(SW_THREAD thread, SW_BOOL flag);
SW_API SW_BOOL SW_GetThreadExitFlag(SW_THREAD thread);
SW_API SW_BOOL SW_GetThreadExitFlagSelf(SW_VOID);
SW_API SW_RET SW_WaitThreadExit(SW_THREAD thread);
SW_API SW_RET SW_ExitThread(SW_UINT32 code);
SW_API SW_RET SW_SetThreadStatInterval(SW_UINT32 sec);
SW_API SW_UINT32 SW_GetThreadStatInterval(SW_VOID);
SW_API SW_THREAD_ONCE SW_CreateThreadOnce(SW_VOID);
SW_API SW_RET SW_DeleteThreadOnce(SW_THREAD_ONCE once);
SW_API SW_RET SW_RunThreadOnce(SW_THREAD_ONCE once, SW_THREAD_ONCE_PROC proc);
SW_API SW_RET SW_CmdThread(const SW_CHAR *pSortStr, SW_ORDER order);
SW_API SW_RET SW_CmdSetThreadStatInterval(SW_UINT32 sec);

#ifdef __cplusplus
}
#endif

#endif

